/*
 *     This file is part of Neptune Network Emulator.
 *
 *  Neptune Network Emulator is free software: 
 *  you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Neptune Network Emulator is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Neptune Network Emulator.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
/**
 *
 */
package neptune.web.client.view.components.dialogs;


import neptune.web.client.WebInterface;
import neptune.web.client.model.SerializableApplicationProperties;
import neptune.web.client.services.SystemService;
import neptune.web.client.view.components.MessageWidget;
import neptune.web.client.view.input.IPInputValidator;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * @author Luigi Lorenzo Arpino [luigiarpino@yahoo.it]
 *
 */
public class EditConfigurationDialog extends DialogBox implements ClickListener 
{
	
	private TextBox textvmTemplatesDir;
	private TextBox textExperimentsVMsDir;
	private CheckBox checkBoxDebug;
	private TextBox textNetmaskControlIpRange;
	private TextBox textStartIpControlIpRange;
	private TextBox textEndIpControlIpRange;
	private TextBox textGatewayControlIpRange;
	private TextBox textAddressClusterSubnet;
	private TextBox textNetmaskClusterSubnet;
	private TextBox textBaseAddressExperimentSubnet;
	private TextBox textNetmaskExperimentSubnet;
	private TextBox textNetmaskLinkSubnet;
	
	
	public EditConfigurationDialog()
	{
		super(false, true);

		FlexTable mainPanel = new FlexTable();
		mainPanel.setWidth("95%");
		ScrollPanel mainPanelWrapper = new ScrollPanel(mainPanel);
		mainPanelWrapper.setHeight("350px");

		// vmTemplatesDir
		Label labelvmTemplatesDir = new Label("VMs Templates Dir");
		labelvmTemplatesDir.addStyleName("NodePropsDialog-label");
		this.textvmTemplatesDir = new TextBox();
		this.textvmTemplatesDir.addStyleName("NodePropsDialog-input");
		mainPanel.setWidget(0, 0, labelvmTemplatesDir);
		mainPanel.setWidget(0, 1, this.textvmTemplatesDir );
		
		//ExperimentsVMsDir
		Label labelExperimentsVMsDir = new Label("Experiments VMs Dir");
		labelExperimentsVMsDir.addStyleName("NodePropsDialog-label");
		this.textExperimentsVMsDir = new TextBox();
		this.textExperimentsVMsDir.addStyleName("NodePropsDialog-input");
		//this.textIdPhysicalMachine.setEnabled(false);
		mainPanel.setWidget(1, 0, labelExperimentsVMsDir);
		mainPanel.setWidget(1, 1, this.textExperimentsVMsDir );
		
		//debug
		Label labelDebug=new Label("Active Debug Mode"); 
		this.checkBoxDebug=new CheckBox();
		mainPanel.setWidget(2, 0, labelDebug);
		mainPanel.setWidget(2, 1, this.checkBoxDebug);
		
		// controlIpRanges
		DisclosurePanel controlIpRangePanel = new DisclosurePanel("Control Ip Range");
		controlIpRangePanel.addStyleName("NodePropsDialog-inputPanel");
		controlIpRangePanel.setAnimationEnabled(true);
		controlIpRangePanel.setWidth("100%");
		mainPanel.setWidget(3, 0, controlIpRangePanel);
		mainPanel.getFlexCellFormatter().setColSpan(3, 0, 2);
		
		FlexTable controlIpRangeTable = new FlexTable();
		controlIpRangeTable.setWidth("100%");
		controlIpRangePanel.add(controlIpRangeTable);

		// Netmask control Ip range
		Label netmaskLabel = new Label("Netmask");
		netmaskLabel.addStyleName("NodePropsDialog-label");
		this.textNetmaskControlIpRange = new TextBox();
		this.textNetmaskControlIpRange.addStyleName("NodePropsDialog-input");
		controlIpRangeTable.setWidget(0, 0, netmaskLabel);
		controlIpRangeTable.setWidget(0, 1, this.textNetmaskControlIpRange);

		// startIP control Ip range
		Label startIpLabel = new Label("Start Ip");
		startIpLabel.addStyleName("NodePropsDialog-label");
		this.textStartIpControlIpRange = new TextBox();
		this.textStartIpControlIpRange.addStyleName("NodePropsDialog-input");
		controlIpRangeTable.setWidget(1, 0, startIpLabel);
		controlIpRangeTable.setWidget(1, 1, this.textStartIpControlIpRange);

		// endIP control Ip range
		Label endIpLabel = new Label("End Ip");
		endIpLabel.addStyleName("NodePropsDialog-label");
		this.textEndIpControlIpRange = new TextBox();
		this.textEndIpControlIpRange.addStyleName("NodePropsDialog-input");
		controlIpRangeTable.setWidget(2, 0, endIpLabel);
		controlIpRangeTable.setWidget(2, 1, this.textEndIpControlIpRange);
		
		//gateway ControlIpRange;
		Label gatewayIpLabel=new Label("Gateway");
		gatewayIpLabel.addStyleName("NodePropsDialog-label");
		this.textGatewayControlIpRange = new TextBox();
		this.textGatewayControlIpRange.addStyleName("NodePropsDialog-input");
		controlIpRangeTable.setWidget(3, 0, gatewayIpLabel);
		controlIpRangeTable.setWidget(3, 1,this.textGatewayControlIpRange);
		
		// ClusterSubnet
		DisclosurePanel clusterSubnetPanel = new DisclosurePanel("Cluster subnet");
		clusterSubnetPanel.addStyleName("NodePropsDialog-inputPanel");
		clusterSubnetPanel.setAnimationEnabled(true);
		clusterSubnetPanel.setWidth("100%");
		mainPanel.setWidget(4, 0, clusterSubnetPanel);
		mainPanel.getFlexCellFormatter().setColSpan(4, 0, 2);
		
		FlexTable clusterSubnetTable = new FlexTable();
		clusterSubnetTable.setWidth("100%");
		clusterSubnetPanel.add(clusterSubnetTable);
		
		// address
		Label addressLabel = new Label("Address");
		addressLabel.addStyleName("NodePropsDialog-label");
		this.textAddressClusterSubnet = new TextBox();
		this.textAddressClusterSubnet.addStyleName("NodePropsDialog-input");
		clusterSubnetTable.setWidget(0, 0, addressLabel);
		clusterSubnetTable.setWidget(0, 1, this.textAddressClusterSubnet);
		
		// netmask
		Label netmaskClusterSubnetLabel = new Label("Netmask");
		netmaskClusterSubnetLabel.addStyleName("NodePropsDialog-label");
		this.textNetmaskClusterSubnet= new TextBox();
		this.textNetmaskClusterSubnet.addStyleName("NodePropsDialog-input");
		clusterSubnetTable.setWidget(1, 0, netmaskClusterSubnetLabel);
		clusterSubnetTable.setWidget(1, 1, this.textNetmaskClusterSubnet);
		
		
		//experimentsSubnet
		DisclosurePanel experimentSubnetPanel = new DisclosurePanel("Experiment subnet");
		experimentSubnetPanel.addStyleName("NodePropsDialog-inputPanel");
		experimentSubnetPanel.setAnimationEnabled(true);
		experimentSubnetPanel.setWidth("100%");
		mainPanel.setWidget(5, 0, experimentSubnetPanel);
		mainPanel.getFlexCellFormatter().setColSpan(5, 0, 2);
		
		FlexTable experimentSubnetTable = new FlexTable();
		experimentSubnetTable.setWidth("100%");
		experimentSubnetPanel.add(experimentSubnetTable);
		
		// address
		Label baseAddressLabel = new Label("Base Address");
		baseAddressLabel.addStyleName("NodePropsDialog-label");
		this.textBaseAddressExperimentSubnet = new TextBox();
		this.textBaseAddressExperimentSubnet.addStyleName("NodePropsDialog-input");
		experimentSubnetTable.setWidget(0, 0, baseAddressLabel);
		experimentSubnetTable.setWidget(0, 1, this.textBaseAddressExperimentSubnet);
		
		//netmask
		Label netmaskExperimentSubnetLabel = new Label("Netmask");
		netmaskExperimentSubnetLabel.addStyleName("NodePropsDialog-label");
		this.textNetmaskExperimentSubnet = new TextBox();
		this.textNetmaskExperimentSubnet.addStyleName("NodePropsDialog-input");
		experimentSubnetTable.setWidget(1, 0, netmaskExperimentSubnetLabel);
		experimentSubnetTable.setWidget(1, 1, this.textNetmaskExperimentSubnet);
		
		//linkSubnet 
		Label linkSubnetTemplatesDirLabel = new Label("Link Subnet");
		linkSubnetTemplatesDirLabel.addStyleName("NodePropsDialog-label");
		this.textNetmaskLinkSubnet = new TextBox();
		this.textNetmaskLinkSubnet.addStyleName("NodePropsDialog-input");
		mainPanel.setWidget(6, 0, linkSubnetTemplatesDirLabel);
		mainPanel.setWidget(6, 1, this.textNetmaskLinkSubnet );
		
		
		// BUTTON PANEL
		HorizontalPanel buttonPanel = new HorizontalPanel();
		Button buttonOK = new Button("Ok");
		buttonOK.addClickListener(this);
		buttonOK.addStyleName("NodePropsDialog-button");
		Button buttonCancel = new Button("Cancel");
		buttonCancel.addClickListener(this);
		buttonCancel.addStyleName("NodePropsDialog-button");
		buttonPanel.add(buttonOK);
		buttonPanel.add(buttonCancel);

		VerticalPanel vPanel = new VerticalPanel();
		vPanel.setWidth("100%");
		vPanel.add(mainPanelWrapper);
		vPanel.add(buttonPanel);
		vPanel.setCellHorizontalAlignment(buttonPanel,
				VerticalPanel.ALIGN_RIGHT);

		this.setWidget(vPanel);
		this.setText("Edit Configuration");

		// Styles
		mainPanelWrapper.addStyleName("NodePropsDialog-mainWrapper");
		mainPanel.addStyleName("NodePropsDialog-mainPanel");
		this.addStyleName("NodePropsDialog");
		
		// Riempio i campi
		SystemService.Util.getInstance().getSystemConfiguration(new AsyncCallback<SerializableApplicationProperties>()
		{

			public void onFailure(Throwable caught) 
			{
				String message=new String("\n Unable to read system properties cause: "+caught.getMessage() );
            	WebInterface.addMessageToConsoleAndShowDialog(message,true);
			}

			public void onSuccess(SerializableApplicationProperties appProp) 
			{
				textvmTemplatesDir.setText(appProp.getVmTemplatesDir());
				textExperimentsVMsDir.setText(appProp.getExperimentsVMsDir());
				//
				checkBoxDebug.setChecked(appProp.getIsDebug());
				//
				textNetmaskControlIpRange.setText(appProp.getNetmaskControlIpRange());
				textStartIpControlIpRange.setText(appProp.getStartIpControlIpRange());
				textEndIpControlIpRange.setText(appProp.getEndIpControlIpRange());
				textGatewayControlIpRange.setText(appProp.getGatewayControlIpRange());
				//
				textAddressClusterSubnet.setText(appProp.getAddressClusterSubnet());
				textNetmaskClusterSubnet.setText(appProp.getNetmaskClusterSubnet());
				//
				textBaseAddressExperimentSubnet.setText(appProp.getBaseAddressExperimentSubnet());
				textNetmaskExperimentSubnet.setText(appProp.getNetmaskExperimentSubnet());
				//
				textNetmaskLinkSubnet.setText(appProp.getNetmaskLinkSubnet());
			}
		});
		
	}

	/* (non-Javadoc)
	 * @see com.google.gwt.user.client.ui.ClickListener#onClick(com.google.gwt.user.client.ui.Widget)
	 */
	public void onClick(Widget sender) 
	{
		if (((Button) sender).getText().equalsIgnoreCase("Ok")) 
		{
			if(this.isInputDataValid())
			{
				this.hide();
				// convalido i dati
				
				// Leggo i dati
				SerializableApplicationProperties serAppProperties=new SerializableApplicationProperties();
				serAppProperties.setVmTemplatesDir(this.textvmTemplatesDir.getText());
				serAppProperties.setExperimentsVMsDir(this.textExperimentsVMsDir.getText());
				serAppProperties.setIsDebug(this.checkBoxDebug.isChecked());
				serAppProperties.setNetmaskControlIpRange(this.textNetmaskControlIpRange.getText());
				serAppProperties.setStartIpControlIpRange(this.textStartIpControlIpRange.getText());
				serAppProperties.setEndIpControlIpRange(this.textEndIpControlIpRange.getText());
				serAppProperties.setGatewayControlIpRange(this.textGatewayControlIpRange.getText());
				serAppProperties.setAddressClusterSubnet(this.textAddressClusterSubnet.getText());
				serAppProperties.setNetmaskClusterSubnet(this.textNetmaskClusterSubnet.getText());
				serAppProperties.setBaseAddressExperimentSubnet(this.textBaseAddressExperimentSubnet.getText());
				serAppProperties.setNetmaskExperimentSubnet(this.textNetmaskExperimentSubnet.getText());
				serAppProperties.setNetmaskLinkSubnet(this.textNetmaskLinkSubnet.getText());
				// Aggiorno i dati
				String message = "Edit Application Properties ...";
				final PopupPanel popup = WebInterface.showMessageDialog(
						new MessageWidget(MessageWidget.LOADING, message), false);
				SystemService.Util.getInstance().updateSystemConfiguration(serAppProperties, new AsyncCallback<Boolean>()
				{
	
					public void onFailure(Throwable caught) 
					{
						popup.hide();
		            	String message=new String("Error cause: "+caught.getMessage() );
		            	WebInterface.addMessageToConsoleAndShowDialog(message,true);
					}
	
					public void onSuccess(Boolean result) 
					{
						popup.hide();
						String message=new String("Edit Application Properties ...[ OK ]");
		            	WebInterface.addMessageToConsoleAndShowDialog(message,false);
					}
					
				});
			}
			else
			{
				// I DATI INSERITI NON SONO VALIDI
			}
		}
		else
		{
			this.hide();
		}
	}
	
	private boolean isInputDataValid()
	{
		//Netmask ControlIpRange
		this.textNetmaskControlIpRange.removeStyleName("NodePropsDialog-input-error");
		IPInputValidator  ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textNetmaskControlIpRange.getText() ))
		{
			this.textNetmaskControlIpRange.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		//StartIp ControlIpRange
		this.textStartIpControlIpRange.removeStyleName("NodePropsDialog-input-error");
		ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textStartIpControlIpRange.getText() ))
		{
			this.textStartIpControlIpRange.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		// EndIp ControlIpRange
		this.textEndIpControlIpRange.removeStyleName("NodePropsDialog-input-error");
		ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textEndIpControlIpRange.getText() ))
		{
			this.textEndIpControlIpRange.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		// gateway Control ip raange
		this.textGatewayControlIpRange.removeStyleName("NodePropsDialog-input-error");
		ipValidator=new IPInputValidator();
		if( !ipValidator.isValid(this.textGatewayControlIpRange.getText()))
		{
			this.textGatewayControlIpRange.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		// Address ClusterSubnet
		this.textAddressClusterSubnet.removeStyleName("NodePropsDialog-input-error");
		ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textAddressClusterSubnet.getText() ))
		{
			this.textAddressClusterSubnet.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		//Netmask ClusterSubnet
		this.textNetmaskClusterSubnet.removeStyleName("NodePropsDialog-input-error");
		ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textNetmaskClusterSubnet.getText() ))
		{
			this.textNetmaskClusterSubnet.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		//BaseAddress ExperimentSubnet
		this.textBaseAddressExperimentSubnet.removeStyleName("NodePropsDialog-input-error");
		ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textBaseAddressExperimentSubnet.getText() ))
		{
			this.textBaseAddressExperimentSubnet.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		//Netmask ExperimentSubnet
		this.textNetmaskExperimentSubnet.removeStyleName("NodePropsDialog-input-error");
		ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textNetmaskExperimentSubnet.getText() ))
		{
			this.textNetmaskExperimentSubnet.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		//Netmask LinkSubnet
		this.textNetmaskLinkSubnet.removeStyleName("NodePropsDialog-input-error");
		ipValidator=new IPInputValidator();
		if ( !ipValidator.isValid(this.textNetmaskLinkSubnet.getText() ))
		{
			this.textNetmaskLinkSubnet.addStyleName("NodePropsDialog-input-error");
			return false;
		}
		return true;
	}

}
